package cn.iocoder.yudao.module.resource.service.audiotone;

import cn.hutool.extra.spring.SpringUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.redis.core.RedisPublishClient;
import cn.iocoder.yudao.module.infra.service.file.FileService;
import cn.iocoder.yudao.module.infra.service.file.UploadFileResult;
import cn.iocoder.yudao.module.resource.common.LmrobotResourceConfig;
import cn.iocoder.yudao.module.resource.common.MemoryCacheService;
import cn.iocoder.yudao.module.resource.common.event.AudioToneUpdateEvent;
import cn.iocoder.yudao.module.resource.controller.admin.audiotone.vo.AudioTonePageReqVO;
import cn.iocoder.yudao.module.resource.controller.admin.audiotone.vo.AudioToneRespVO;
import cn.iocoder.yudao.module.resource.controller.admin.audiotone.vo.AudioToneSaveReqVO;
import cn.iocoder.yudao.module.resource.dal.dataobject.audiotone.AudioToneDO;
import cn.iocoder.yudao.module.resource.dal.mysql.audiotone.AudioToneMapper;
import jakarta.annotation.Resource;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.resource.enums.ErrorCodeConstants.AUDIO_TONE_NOT_EXISTS;

/**
 * 声纹管理 Service 实现类
 *
 * @author wgs
 */
@Service
@Validated
public class AudioToneServiceImpl extends MemoryCacheService<Integer, AudioToneDO> implements AudioToneService, ApplicationListener<AudioToneUpdateEvent> {

    @Resource
    private AudioToneMapper audioToneMapper;
    @Resource
    private FileService fileService;

    public AudioToneServiceImpl(LmrobotResourceConfig resourceConfig) {
        super(resourceConfig);
    }

    @Override
    protected AudioToneDO loadEntity(Integer key) {
        return audioToneMapper.selectById(key);
    }

    @Override
    public void onApplicationEvent(AudioToneUpdateEvent event) {
        this.delete(event.getAudioToneId());
    }

    @Override
    public Integer createAudioTone(AudioToneSaveReqVO createReqVO) {
        this.fileService.checkFileExist(createReqVO.getFileId());
        // 插入
        AudioToneDO audioTone = BeanUtils.toBean(createReqVO, AudioToneDO.class);
        audioToneMapper.insert(audioTone);
        // 返回
        return audioTone.getId();
    }

    @Override
    public void updateAudioTone(AudioToneSaveReqVO updateReqVO) {
        // 校验存在
        validateAudioToneExists(updateReqVO.getId());
        this.fileService.checkFileExist(updateReqVO.getFileId());
        // 更新
        AudioToneDO updateObj = BeanUtils.toBean(updateReqVO, AudioToneDO.class);
        audioToneMapper.updateById(updateObj);
        this.sendUpdateEvent(updateObj.getId());
    }

    private void sendUpdateEvent(Integer id) {
        AudioToneUpdateEvent audioToneUpdateEvent = new AudioToneUpdateEvent();
        audioToneUpdateEvent.setAudioToneId(id);
        RedisPublishClient redisPublishClient = SpringUtil.getBean(RedisPublishClient.class);
        redisPublishClient.publishMsg(audioToneUpdateEvent);
    }

    @Override
    public void updateAudioToneById(AudioToneDO tone) {
        audioToneMapper.updateById(tone);
        this.sendUpdateEvent(tone.getId());
    }

    @Override
    public void deleteAudioTone(Integer id) {
        // 校验存在
        validateAudioToneExists(id);
        // 删除
        audioToneMapper.deleteById(id);
        this.sendUpdateEvent(id);
    }

    private void validateAudioToneExists(Integer id) {
        if (audioToneMapper.selectById(id) == null) {
            throw exception(AUDIO_TONE_NOT_EXISTS);
        }
    }

    @Override
    public AudioToneDO getAudioTone(Integer id) {
        return this.getFromCacheByKey(id);
    }

    @Override
    public void setFileUrl(AudioToneRespVO audioToneDO) {

        UploadFileResult uploadFileResult = fileService.getFile(audioToneDO.getFileId(), 600);
        if (uploadFileResult != null) {
            audioToneDO.setFileUrl(uploadFileResult.getFileUrl());
        }
    }

    @Override
    public PageResult<AudioToneDO> getAudioTonePage(AudioTonePageReqVO pageReqVO) {
        return audioToneMapper.selectPage(pageReqVO);
    }

    @Override
    public void setCloneVoiceId(Integer id, String cloneVoiceId) {
        final AudioToneDO record = new AudioToneDO();
        record.setId(id);
        record.setCloneVoiceId(cloneVoiceId);
        audioToneMapper.updateById(record);
    }
}